package com.watson.onebox.algorithm.descarte;

import com.alibaba.fastjson.JSON;

import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class Descarte {
    List<String> list = new Prefix<>(new Prefix<>(new Prefix<>(null,"a"),"b"),"c")
            .addTo(new ArrayList<>()); // [a, b, c];

    private static <T, C extends Collection< T >> Stream<C> comb(
            List<? extends Collection< T >> values, int offset, Prefix< T > prefix,
            Supplier<C> supplier) {
        if (offset == values.size() - 1)
            return values.get(offset).stream()
                    .map(e -> new Prefix<>(prefix, e).addTo(supplier.get()));
        return values.get(offset).stream()
                .flatMap(e -> comb(values, offset + 1, new Prefix<>(prefix, e), supplier));
    }

    public static <T, C extends Collection< T >> Stream<C> ofCombinations(
            Collection<? extends Collection< T >> values, Supplier<C> supplier) {
        if (values.isEmpty())
            return Stream.empty();
        return comb(new ArrayList<>(values), 0, null, supplier);
    }

    public static class Prefix<T> {
        final T value;
        final Prefix< T > parent;

        Prefix(Prefix< T > parent, T value) {
            this.parent = parent;
            this.value = value;
        }

        // put the whole prefix into given collection
        <C extends Collection< T >> C addTo(C collection) {
            if (parent != null)
                parent.addTo(collection);
            collection.add(value);
            return collection;
        }
    }

    public static void main(String[] args) {
        List<String> tmp = new ArrayList<>();
        tmp.add("123");
        tmp.add("1232");
        tmp.add("1233");
        tmp.add("1234");
        tmp.set(2,"32");
        Map<String, Collection<String>> map = new LinkedHashMap<>(); // to preserve the order
        map.put("A", Arrays.asList("a1","a2"));
        map.put("B", Arrays.asList("b1","b2","b3"));
        map.put("C", Arrays.asList("c1","c2"));

        ofCombinations(map.values(), LinkedHashSet::new).forEach(System.out::println);

        Map<String, List<Object>> paramMap = new HashMap<>();
        List<Object> erp = new ArrayList<>();
        erp.add("123");
        erp.add("213");
        paramMap.put("erp", erp);

        List<Object> tab = new ArrayList<>();
        tab.add("123");
        tab.add("213");
        paramMap.put("tab", tab);


        List<Object> system = new ArrayList<>();
        List<String> abc1 = new ArrayList<>();
        abc1.add("fa");
        abc1.add("e1f");
        system.add(abc1);
        List<String> abc2 = new ArrayList<>();
        abc2.add("1313");
        abc2.add("fewo");
        system.add(abc2);
        paramMap.put("systems", system);

        Object objectValue = new ClassUtil().getObjectValue(TableVo.class, paramMap);

        System.out.println(objectValue);
    }
}
